using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;
using FIRADriverLibrary;
using GeometryCSharp;
using AGHFiraPlayer.Drivers;
using AGHFiraPlayer.Strategies;
using AGHFiraPlayer.Strategies.StrategiesImpl;

namespace AGHFiraPlayer
{
	public class PotencialDriverForm : System.Windows.Forms.Form
	{
		private const float robotDiameter = 0.075f;
		private const float ballDiameter = 0.036f;
		private System.ComponentModel.IContainer components;

        public static DataTable dataTable;
        private DataGridView grid;
        private System.Windows.Forms.SplitContainer splitContainer;
		private System.Windows.Forms.Panel legtPanel;
		private System.Windows.Forms.Panel viewPanel;
		private System.Windows.Forms.Splitter splitter1;
		private System.Windows.Forms.Label label1;
		private System.Windows.Forms.Label statuSLabel;
		private System.Windows.Forms.Button requestButton;
        private System.Windows.Forms.Button requestFirst5Button;
		private System.Windows.Forms.Label rightStatusLabel;
		private System.Windows.Forms.Label middleStatusLabel;
		private System.Windows.Forms.Button releaseButton;
		private System.Windows.Forms.Timer interfaceRefreshTimer;
		private System.Windows.Forms.Label label3;
		private System.Windows.Forms.NumericUpDown fpsNumericUpDown;		
		private System.Windows.Forms.CheckBox fpsEnabledCheckBox;
		private System.Windows.Forms.Button createCoachButton;
		private System.Windows.Forms.RadioButton haltRadioButton;
		private System.Windows.Forms.RadioButton playRadioButton;
		private System.Windows.Forms.GroupBox gameStateGroupBox;
		private System.Windows.Forms.RadioButton startPositionsRadioButton;
	
		private double oldTime;
		private Thread refreshThread = null;
		private bool killThread = false;
		private Mutex firaDriverMutex = null;

        private AGHDriver aghDriver;
		private FIRADriver firaDriver;
		private RectangleF pitchArea;
		private float goalWidth;

		private TheCoachOf5 theCoach;

		private Bitmap viewBitmap;
		private Graphics viewPanelGraphics;

		private float viewScale;
		private PointF viewOffset;

		private Brush pithBrush = (new Pen(Color.Black)).Brush;
		private Pen pithPen = new Pen(Color.LightGray, 3);
		private Pen robotPen = new Pen(Color.LightGreen, 1);
		private Pen ownedRobotPen = new Pen(Color.Blue, 2);
		private Brush ownedRobotOBrush = new Pen(Color.LightSalmon, 1).Brush;
		private Brush ownedRobotDBrush = new Pen(Color.LightBlue, 1).Brush;
		private Pen ballPen = new Pen(Color.Orange, 1);
		private Pen ballPPen = new Pen(Color.Brown, 1);
		private Pen targetPen = new Pen(Color.Red, 1);

		private int robotDiameterView;
		private int ballDiameterView;
		private System.Windows.Forms.TrackBar maxVelocityTrackBar;
        private System.Windows.Forms.Label maxVelocityLabel;
        private CheckedListBox checkedListBox1;
        private Button pickSelectedOnlyButton;
        private Button pickAllButton;

		Point2D targetPoint;


        public PotencialDriverForm(FIRADriver firaDriver, RectangleF pitchArea, float goalWidth, bool invertPitch)
		{
            aghDriver = new AGHDriver(ref firaDriver, pitchArea, goalWidth);
            Predicator.firaDriver = firaDriver;
            Predicator.aghDriver = aghDriver;
            Predicator.pitchArea = pitchArea;
            Strategies.StrategiesManager.init(aghDriver);
            SimpleFunctions.init(aghDriver);

			this.firaDriver = firaDriver;
			this.goalWidth = goalWidth;
			this.pitchArea = pitchArea;
			if (invertPitch)
				firaDriver.EnablePitchInvertion(pitchArea.Width + 2*pitchArea.Left, pitchArea.Height + 2*pitchArea.Top );
			InitializeComponent();

            FillDataTable();
			CreateViewDrawer();

			firaDriverMutex = new Mutex();
			refreshThread = new Thread(new ThreadStart(this.RefreshThread));
			refreshThread.Priority = ThreadPriority.AboveNormal;
			refreshThread.Start();

			interfaceRefreshTimer.Enabled = true;
		}

		private void RefreshThread()
		{
			oldTime = -1.0;
			while (true)
			{
				firaDriverMutex.WaitOne();
				firaDriver.Step();

				if (firaDriver.time < oldTime - 1)	//time reset occured
					oldTime = firaDriver.time;

				if (firaDriver.time > oldTime)
				{
					Predicator.Refresh();	

					if (theCoach != null)
						theCoach.Refresh();						
					
					//rightStatusLabel.Text = firaDriver.time.ToString("f3");
					oldTime = (fpsEnabledCheckBox.Checked?firaDriver.time + 1/(double)fpsNumericUpDown.Value:firaDriver.time);
					firaDriverMutex.ReleaseMutex();	//after
				}
				else 
				{
					firaDriverMutex.ReleaseMutex();	//before
					Thread.Sleep(1);
				}
				if (killThread)
					return;
			}
		}

        private void FillDataTable()
        {
            dataTable.Columns.Add("Robot", typeof(FIRARobotState));
            dataTable.Columns.Add("Strategy", typeof(AbstractStrategy));
            dataTable.Columns.Add("Applicability", typeof(int));

            foreach (FIRARobotState robot in firaDriver.firaRobots)
            {
                dataTable.Rows.Add(robot, null, 0);
            }
        }

		private void CreateViewDrawer()
		{
			if (viewBitmap != null)
				viewBitmap.Dispose();
			if (viewPanelGraphics != null)
				viewPanelGraphics.Dispose();

			viewPanelGraphics = viewPanel.CreateGraphics();
			viewPanelGraphics.Clear(SystemColors.ControlDarkDark);
			viewBitmap = new Bitmap(Math.Max(1,viewPanel.Width), Math.Max(1,viewPanel.Height));
			Graphics viewBitmapGraphics = Graphics.FromImage(viewBitmap);

			viewScale = (float)Math.Min(viewPanel.Width / (1.2f * pitchArea.Width),
				viewPanel.Height / (1.1f * pitchArea.Height)); 
			viewOffset = new PointF(-pitchArea.X + pitchArea.Width * 0.1f,
				-pitchArea.Y + pitchArea.Width * 0.05f);


			//goals border
			viewBitmapGraphics.DrawRectangle(pithPen,Real2ViewX(pitchArea.X-pitchArea.Width * 0.05f),Real2ViewY(pitchArea.Y + pitchArea.Height/2 - goalWidth/2),
				(pitchArea.Width*1.1f)*viewScale, goalWidth*viewScale);
			//pitch
			viewBitmapGraphics.FillRectangle(pithBrush,Real2ViewX(pitchArea.X),Real2ViewY(pitchArea.Y),
				pitchArea.Width*viewScale, pitchArea.Height*viewScale);
			viewBitmapGraphics.DrawRectangle(pithPen,Real2ViewX(pitchArea.X),Real2ViewY(pitchArea.Y),
				pitchArea.Width*viewScale, pitchArea.Height*viewScale);

			//goals
			viewBitmapGraphics.FillRectangle(pithBrush,Real2ViewX(pitchArea.X-pitchArea.Width * 0.05f),Real2ViewY(pitchArea.Y + pitchArea.Height/2 - goalWidth/2),
				(pitchArea.Width*1.1f)*viewScale, goalWidth*viewScale);
			
			robotDiameterView = (int)(robotDiameter * viewScale);
			ballDiameterView = (int)(ballDiameter * viewScale);


			viewBitmapGraphics.Dispose();
			viewPanel_Paint(this,null);
		}

		private int Real2ViewX(double realX)
		{
			return (int)((realX + viewOffset.X) * viewScale);
		}
		private int Real2ViewY(double realY)
		{
			return (int)((realY + viewOffset.Y) * viewScale);
		}


		private double View2RealX(int x)
		{
			return (double)x / viewScale - viewOffset.X;
		}
		private double View2RealY(int y)
		{
			return (double)y / viewScale - viewOffset.Y;
		}


		protected override void Dispose( bool disposing )
		{
			interfaceRefreshTimer.Enabled = false;
			killThread = true;

			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
            this.components = new System.ComponentModel.Container();
            dataTable = new System.Data.DataTable();
            this.grid = new System.Windows.Forms.DataGridView();
            this.legtPanel = new System.Windows.Forms.Panel();
            this.gameStateGroupBox = new System.Windows.Forms.GroupBox();
            this.haltRadioButton = new System.Windows.Forms.RadioButton();
            this.startPositionsRadioButton = new System.Windows.Forms.RadioButton();
            this.playRadioButton = new System.Windows.Forms.RadioButton();
            this.createCoachButton = new System.Windows.Forms.Button();
            this.fpsEnabledCheckBox = new System.Windows.Forms.CheckBox();
            this.fpsNumericUpDown = new System.Windows.Forms.NumericUpDown();
            this.label3 = new System.Windows.Forms.Label();
            this.requestButton = new System.Windows.Forms.Button();
            this.requestFirst5Button = new System.Windows.Forms.Button();
            this.label1 = new System.Windows.Forms.Label();
            this.releaseButton = new System.Windows.Forms.Button();
            this.maxVelocityTrackBar = new System.Windows.Forms.TrackBar();
            this.maxVelocityLabel = new System.Windows.Forms.Label();
            this.splitContainer = new System.Windows.Forms.SplitContainer();
            this.pickSelectedOnlyButton = new System.Windows.Forms.Button();
            this.checkedListBox1 = new System.Windows.Forms.CheckedListBox();
            this.pickAllButton = new System.Windows.Forms.Button();
            this.viewPanel = new System.Windows.Forms.Panel();
            this.splitter1 = new System.Windows.Forms.Splitter();
            this.statuSLabel = new System.Windows.Forms.Label();
            this.rightStatusLabel = new System.Windows.Forms.Label();
            this.middleStatusLabel = new System.Windows.Forms.Label();
            this.interfaceRefreshTimer = new System.Windows.Forms.Timer(this.components);
            ((System.ComponentModel.ISupportInitialize)(dataTable)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.grid)).BeginInit();
            this.legtPanel.SuspendLayout();
            this.gameStateGroupBox.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.fpsNumericUpDown)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.maxVelocityTrackBar)).BeginInit();
            this.splitContainer.Panel1.SuspendLayout();
            this.splitContainer.Panel2.SuspendLayout();
            this.splitContainer.SuspendLayout();
            this.SuspendLayout();
            // 
            // grid
            // 
            this.grid.AllowUserToAddRows = false;
            this.grid.AllowUserToDeleteRows = false;
            this.grid.AllowUserToResizeRows = false;
            this.grid.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.grid.DataSource = dataTable;
            this.grid.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically;
            this.grid.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
            this.grid.Location = new System.Drawing.Point(8, 42);
            this.grid.MultiSelect = false;
            this.grid.Name = "grid";
            this.grid.ReadOnly = true;
            this.grid.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
            this.grid.Size = new System.Drawing.Size(368, 245);
            this.grid.TabIndex = 0;
            // 
            // legtPanel
            // 
            this.legtPanel.Controls.Add(this.gameStateGroupBox);
            this.legtPanel.Controls.Add(this.createCoachButton);
            this.legtPanel.Controls.Add(this.fpsEnabledCheckBox);
            this.legtPanel.Controls.Add(this.fpsNumericUpDown);
            this.legtPanel.Controls.Add(this.label3);
            this.legtPanel.Controls.Add(this.requestButton);
            this.legtPanel.Controls.Add(this.requestFirst5Button);
            this.legtPanel.Controls.Add(this.label1);
            this.legtPanel.Controls.Add(this.grid);
            this.legtPanel.Controls.Add(this.releaseButton);
            this.legtPanel.Controls.Add(this.maxVelocityTrackBar);
            this.legtPanel.Controls.Add(this.maxVelocityLabel);
            this.legtPanel.Location = new System.Drawing.Point(3, 3);
            this.legtPanel.Name = "legtPanel";
            this.legtPanel.Size = new System.Drawing.Size(384, 512);
            this.legtPanel.TabIndex = 0;
            // 
            // gameStateGroupBox
            // 
            this.gameStateGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.gameStateGroupBox.Controls.Add(this.haltRadioButton);
            this.gameStateGroupBox.Controls.Add(this.startPositionsRadioButton);
            this.gameStateGroupBox.Controls.Add(this.playRadioButton);
            this.gameStateGroupBox.Enabled = false;
            this.gameStateGroupBox.Location = new System.Drawing.Point(8, 352);
            this.gameStateGroupBox.Name = "gameStateGroupBox";
            this.gameStateGroupBox.Size = new System.Drawing.Size(352, 64);
            this.gameStateGroupBox.TabIndex = 11;
            this.gameStateGroupBox.TabStop = false;
            this.gameStateGroupBox.Text = "game state";
            // 
            // haltRadioButton
            // 
            this.haltRadioButton.Appearance = System.Windows.Forms.Appearance.Button;
            this.haltRadioButton.Checked = true;
            this.haltRadioButton.Location = new System.Drawing.Point(8, 24);
            this.haltRadioButton.Name = "haltRadioButton";
            this.haltRadioButton.Size = new System.Drawing.Size(48, 24);
            this.haltRadioButton.TabIndex = 0;
            this.haltRadioButton.TabStop = true;
            this.haltRadioButton.Text = "HALT";
            this.haltRadioButton.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            this.haltRadioButton.CheckedChanged += new System.EventHandler(this.gameStateRadioButton_CheckedChanged);
            // 
            // startPositionsRadioButton
            // 
            this.startPositionsRadioButton.Appearance = System.Windows.Forms.Appearance.Button;
            this.startPositionsRadioButton.Location = new System.Drawing.Point(64, 24);
            this.startPositionsRadioButton.Name = "startPositionsRadioButton";
            this.startPositionsRadioButton.Size = new System.Drawing.Size(40, 24);
            this.startPositionsRadioButton.TabIndex = 0;
            this.startPositionsRadioButton.Text = "start";
            this.startPositionsRadioButton.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            this.startPositionsRadioButton.CheckedChanged += new System.EventHandler(this.gameStateRadioButton_CheckedChanged);
            // 
            // playRadioButton
            // 
            this.playRadioButton.Appearance = System.Windows.Forms.Appearance.Button;
            this.playRadioButton.Location = new System.Drawing.Point(112, 24);
            this.playRadioButton.Name = "playRadioButton";
            this.playRadioButton.Size = new System.Drawing.Size(48, 24);
            this.playRadioButton.TabIndex = 0;
            this.playRadioButton.Text = "play";
            this.playRadioButton.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            this.playRadioButton.CheckedChanged += new System.EventHandler(this.gameStateRadioButton_CheckedChanged);
            // 
            // createCoachButton
            // 
            this.createCoachButton.Anchor = System.Windows.Forms.AnchorStyles.Top;
            this.createCoachButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
            this.createCoachButton.Location = new System.Drawing.Point(8, 322);
            this.createCoachButton.Name = "createCoachButton";
            this.createCoachButton.Size = new System.Drawing.Size(136, 24);
            this.createCoachButton.TabIndex = 10;
            this.createCoachButton.Text = "create a coach";
            this.createCoachButton.Click += new System.EventHandler(this.createCoachButton_Click);
            // 
            // fpsEnabledCheckBox
            // 
            this.fpsEnabledCheckBox.Location = new System.Drawing.Point(155, 0);
            this.fpsEnabledCheckBox.Name = "fpsEnabledCheckBox";
            this.fpsEnabledCheckBox.Size = new System.Drawing.Size(40, 24);
            this.fpsEnabledCheckBox.TabIndex = 9;
            this.fpsEnabledCheckBox.Text = "on";
            // 
            // fpsNumericUpDown
            // 
            this.fpsNumericUpDown.Location = new System.Drawing.Point(109, 3);
            this.fpsNumericUpDown.Maximum = new decimal(new int[] {
            500,
            0,
            0,
            0});
            this.fpsNumericUpDown.Minimum = new decimal(new int[] {
            1,
            0,
            0,
            0});
            this.fpsNumericUpDown.Name = "fpsNumericUpDown";
            this.fpsNumericUpDown.Size = new System.Drawing.Size(40, 20);
            this.fpsNumericUpDown.TabIndex = 8;
            this.fpsNumericUpDown.Value = new decimal(new int[] {
            25,
            0,
            0,
            0});
            // 
            // label3
            // 
            this.label3.Location = new System.Drawing.Point(5, 0);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(104, 23);
            this.label3.TabIndex = 7;
            this.label3.Text = "communicator FPS:";
            this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
            // 
            // requestButton
            // 
            this.requestButton.Location = new System.Drawing.Point(8, 293);
            this.requestButton.Name = "requestButton";
            this.requestButton.Size = new System.Drawing.Size(56, 23);
            this.requestButton.TabIndex = 2;
            this.requestButton.Text = "request";
            this.requestButton.Click += new System.EventHandler(this.requestButton_Click);
            // 
            // requestFirst5Button
            // 
            this.requestFirst5Button.Location = new System.Drawing.Point(88, 293);
            this.requestFirst5Button.Name = "requestFirst5Button";
            this.requestFirst5Button.Size = new System.Drawing.Size(96, 23);
            this.requestFirst5Button.TabIndex = 2;
            this.requestFirst5Button.Text = "request first 5";
            this.requestFirst5Button.Click += new System.EventHandler(this.request_First_5_Button_Click);
            // 
            // label1
            // 
            this.label1.Location = new System.Drawing.Point(5, 23);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(48, 16);
            this.label1.TabIndex = 1;
            this.label1.Text = "robots:";
            // 
            // releaseButton
            // 
            this.releaseButton.Location = new System.Drawing.Point(200, 293);
            this.releaseButton.Name = "releaseButton";
            this.releaseButton.Size = new System.Drawing.Size(56, 23);
            this.releaseButton.TabIndex = 2;
            this.releaseButton.Text = "release";
            this.releaseButton.Click += new System.EventHandler(this.releaseButton_Click);
            // 
            // maxVelocityTrackBar
            // 
            this.maxVelocityTrackBar.LargeChange = 2;
            this.maxVelocityTrackBar.Location = new System.Drawing.Point(3, 436);
            this.maxVelocityTrackBar.Maximum = 20;
            this.maxVelocityTrackBar.Minimum = 1;
            this.maxVelocityTrackBar.Name = "maxVelocityTrackBar";
            this.maxVelocityTrackBar.Size = new System.Drawing.Size(168, 45);
            this.maxVelocityTrackBar.TabIndex = 12;
            this.maxVelocityTrackBar.Value = 6;
            this.maxVelocityTrackBar.Scroll += new System.EventHandler(this.maxVelocityTrackBar_Scroll);
            // 
            // maxVelocityLabel
            // 
            this.maxVelocityLabel.Location = new System.Drawing.Point(5, 419);
            this.maxVelocityLabel.Name = "maxVelocityLabel";
            this.maxVelocityLabel.Size = new System.Drawing.Size(144, 23);
            this.maxVelocityLabel.TabIndex = 13;
            this.maxVelocityLabel.Text = "max velocity: 0,6 m/s";
            // 
            // splitContainer
            // 
            this.splitContainer.Dock = System.Windows.Forms.DockStyle.Left;
            this.splitContainer.Location = new System.Drawing.Point(0, 0);
            this.splitContainer.Name = "splitContainer";
            this.splitContainer.Orientation = System.Windows.Forms.Orientation.Horizontal;
            // 
            // splitContainer.Panel1
            // 
            this.splitContainer.Panel1.Controls.Add(this.pickSelectedOnlyButton);
            this.splitContainer.Panel1.Controls.Add(this.checkedListBox1);
            this.splitContainer.Panel1.Controls.Add(this.pickAllButton);
            // 
            // splitContainer.Panel2
            // 
            this.splitContainer.Panel2.Controls.Add(this.legtPanel);
            this.splitContainer.Size = new System.Drawing.Size(384, 636);
            this.splitContainer.SplitterDistance = 160;
            this.splitContainer.TabIndex = 0;
            // 
            // pickSelectedOnlyButton
            // 
            this.pickSelectedOnlyButton.Location = new System.Drawing.Point(268, 32);
            this.pickSelectedOnlyButton.Name = "pickSelectedOnlyButton";
            this.pickSelectedOnlyButton.Size = new System.Drawing.Size(105, 23);
            this.pickSelectedOnlyButton.TabIndex = 2;
            this.pickSelectedOnlyButton.Text = "pick selected only";
            this.pickSelectedOnlyButton.UseVisualStyleBackColor = true;
            this.pickSelectedOnlyButton.Click += new System.EventHandler(this.pickSelectedOnlyButton_Clicked);
            // 
            // checkedListBox1
            // 
            this.checkedListBox1.FormattingEnabled = true;
            this.checkedListBox1.Items.AddRange(StrategiesManager.getAllStrategiesTypes().ToArray());
            this.checkedListBox1.Location = new System.Drawing.Point(3, 3);
            this.checkedListBox1.Name = "checkedListBox1";
            this.checkedListBox1.Size = new System.Drawing.Size(259, 154);
            this.checkedListBox1.TabIndex = 0;
            this.checkedListBox1.CheckOnClick = true;
            for (int i=0; i<this.checkedListBox1.Items.Count; i++) 
            {
                this.checkedListBox1.SetItemChecked(i, true);
            }
            this.checkedListBox1.ItemCheck += new ItemCheckEventHandler(this.strategyPermissionChanged);
            // 
            // pickAllButton
            // 
            this.pickAllButton.Location = new System.Drawing.Point(268, 3);
            this.pickAllButton.Name = "pickAllButton";
            this.pickAllButton.Size = new System.Drawing.Size(105, 23);
            this.pickAllButton.TabIndex = 1;
            this.pickAllButton.Text = "pick all";
            this.pickAllButton.UseVisualStyleBackColor = true;
            this.pickAllButton.Click += new System.EventHandler(this.pickAllButton_Clicked);
            // 
            // viewPanel
            // 
            this.viewPanel.BackColor = System.Drawing.SystemColors.ControlDarkDark;
            this.viewPanel.Dock = System.Windows.Forms.DockStyle.Fill;
            this.viewPanel.Location = new System.Drawing.Point(387, 0);
            this.viewPanel.Name = "viewPanel";
            this.viewPanel.Size = new System.Drawing.Size(517, 636);
            this.viewPanel.TabIndex = 1;
            this.viewPanel.Paint += new System.Windows.Forms.PaintEventHandler(this.viewPanel_Paint);
            this.viewPanel.MouseUp += new System.Windows.Forms.MouseEventHandler(this.viewPanel_MouseUp);
            this.viewPanel.Resize += new System.EventHandler(this.viewPanel_Resize);
            // 
            // splitter1
            // 
            this.splitter1.Location = new System.Drawing.Point(384, 0);
            this.splitter1.MinExtra = 184;
            this.splitter1.MinSize = 184;
            this.splitter1.Name = "splitter1";
            this.splitter1.Size = new System.Drawing.Size(3, 636);
            this.splitter1.TabIndex = 2;
            this.splitter1.TabStop = false;
            // 
            // statuSLabel
            // 
            this.statuSLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.statuSLabel.ForeColor = System.Drawing.SystemColors.ControlDarkDark;
            this.statuSLabel.Location = new System.Drawing.Point(0, 636);
            this.statuSLabel.Name = "statuSLabel";
            this.statuSLabel.Size = new System.Drawing.Size(464, 10);
            this.statuSLabel.TabIndex = 3;
            // 
            // rightStatusLabel
            // 
            this.rightStatusLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.rightStatusLabel.ForeColor = System.Drawing.SystemColors.ControlDarkDark;
            this.rightStatusLabel.Location = new System.Drawing.Point(792, 636);
            this.rightStatusLabel.Name = "rightStatusLabel";
            this.rightStatusLabel.Size = new System.Drawing.Size(112, 12);
            this.rightStatusLabel.TabIndex = 4;
            this.rightStatusLabel.TextAlign = System.Drawing.ContentAlignment.TopRight;
            this.rightStatusLabel.DoubleClick += new System.EventHandler(this.rightStatusLabel_DoubleClick);
            // 
            // middleStatusLabel
            // 
            this.middleStatusLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.middleStatusLabel.ForeColor = System.Drawing.SystemColors.ControlDarkDark;
            this.middleStatusLabel.Location = new System.Drawing.Point(464, 636);
            this.middleStatusLabel.Name = "middleStatusLabel";
            this.middleStatusLabel.Size = new System.Drawing.Size(288, 12);
            this.middleStatusLabel.TabIndex = 5;
            // 
            // interfaceRefreshTimer
            // 
            this.interfaceRefreshTimer.Interval = 200;
            this.interfaceRefreshTimer.Tick += new System.EventHandler(this.interfaceRefreshTimer_Tick);
            // 
            // PotencialDriverForm
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(904, 648);
            this.Controls.Add(this.middleStatusLabel);
            this.Controls.Add(this.statuSLabel);
            this.Controls.Add(this.rightStatusLabel);
            this.Controls.Add(this.viewPanel);
            this.Controls.Add(this.splitter1);
            this.Controls.Add(this.splitContainer);
            this.MinimumSize = new System.Drawing.Size(720, 472);
            this.Name = "PotencialDriverForm";
            this.Padding = new System.Windows.Forms.Padding(0, 0, 0, 12);
            this.Text = "Potencial Driver";
            this.Load += new System.EventHandler(this.PotencialDriverForm_Load);
            ((System.ComponentModel.ISupportInitialize)(dataTable)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.grid)).EndInit();
            this.legtPanel.ResumeLayout(false);
            this.legtPanel.PerformLayout();
            this.gameStateGroupBox.ResumeLayout(false);
            ((System.ComponentModel.ISupportInitialize)(this.fpsNumericUpDown)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.maxVelocityTrackBar)).EndInit();
            this.splitContainer.Panel1.ResumeLayout(false);
            this.splitContainer.Panel2.ResumeLayout(false);
            this.splitContainer.ResumeLayout(false);
            this.ResumeLayout(false);

		}
		#endregion

		[STAThread]
		static void Main() 
		{
			CreateFiraDriverForm createFiraDriverForm = new CreateFiraDriverForm();
			createFiraDriverForm.ShowDialog();
			FIRADriver firaDriver = createFiraDriverForm.FiraDriver;
			if (firaDriver != null)
			{
                Application.Run(new PotencialDriverForm(firaDriver, createFiraDriverForm.PithArea, createFiraDriverForm.GoalWidth, createFiraDriverForm.InvertPitch));
				firaDriver.Dispose();
			}
		}

		private void requestButton_Click(object sender, System.EventArgs e)
		{
			FIRARobotState robot = grid.SelectedRows[0].Cells[0].Value as FIRARobotState;
            requestRobot(robot);
		}

        private void request_First_5_Button_Click(object sender, System.EventArgs e)
        {
            for (int i = 0; i < 5; i++)
            {
                FIRARobotState robot = grid.Rows[i].Cells[0].Value as FIRARobotState;
                requestRobot(robot);
            }
        }

        private void requestRobot(FIRARobotState robot)
        {
            if (robot == null)
                return;
            if (robot.owned)
            {
                MessageBox.Show("Robot already granted.");
                return;
            }
            firaDriverMutex.WaitOne();
            if (firaDriver.RequestRobot(robot.portId) < 0)
            {
                MessageBox.Show("Error requesting robot: " + FIRADriver.lastError);
            }
            firaDriverMutex.ReleaseMutex();

            statuSLabel.Text = "Robot " + robot.portId + " granted!.";
        }

		private void releaseButton_Click(object sender, System.EventArgs e)
		{
            FIRARobotState robot = grid.SelectedRows[0].Cells[0].Value as FIRARobotState;
			if (robot == null)
				return;
			if (!robot.owned)
			{
				MessageBox.Show("Robot not owned.");
				return;
			}
			firaDriverMutex.WaitOne();
			firaDriver.ReleaseRobot(robot.portId);
			firaDriverMutex.ReleaseMutex();
			statuSLabel.Text = "Robot "+robot.portId+" released!.";		
		}

		private void viewPanel_Resize(object sender, System.EventArgs e)
		{
			CreateViewDrawer();
		}

		private void viewPanel_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
		{
			if (viewPanelGraphics==null && viewBitmap==null)
				return;
            
			viewPanelGraphics.DrawImageUnscaled(viewBitmap,0,0);

            /*
			if (theCoach!=null)
			{
				if (theCoach.attacker.main)
					viewPanelGraphics.FillEllipse(ownedRobotOBrush, Real2ViewX(theCoach.attacker.robotState.x)-robotDiameterView/2, Real2ViewY(theCoach.attacker.robotState.y)-robotDiameterView/2, robotDiameterView, robotDiameterView);
				else if (theCoach.defender.main)
					viewPanelGraphics.FillEllipse(ownedRobotDBrush, Real2ViewX(theCoach.defender.robotState.x)-robotDiameterView/2, Real2ViewY(theCoach.defender.robotState.y)-robotDiameterView/2, robotDiameterView, robotDiameterView);
			}
            */

            foreach (FIRARobotState robot in firaDriver.firaRobots)
            {
               	viewPanelGraphics.DrawEllipse((robot.owned?ownedRobotPen:robotPen), Real2ViewX(robot.x)-robotDiameterView/2, Real2ViewY(robot.y)-robotDiameterView/2, robotDiameterView, robotDiameterView);
               	viewPanelGraphics.DrawLine((robot.owned?ownedRobotPen:robotPen),  Real2ViewX(robot.x), Real2ViewY(robot.y), Real2ViewX(robot.x) + (float)(robotDiameterView*Math.Cos(robot.angle)), Real2ViewY(robot.y) + (float)(robotDiameterView*Math.Sin(robot.angle)));
                if (theCoach != null)
                {
                    if (robot != null)
                    {
                        viewPanelGraphics.FillEllipse(ownedRobotOBrush, Real2ViewX(robot.x) - robotDiameterView / 2, Real2ViewY(robot.y) - robotDiameterView / 2, robotDiameterView, robotDiameterView);
                    }
                }
            }
			
			viewPanelGraphics.DrawEllipse(ballPen, Real2ViewX(firaDriver.ballX)-ballDiameterView/2, Real2ViewY(firaDriver.ballY)-ballDiameterView/2, ballDiameterView, ballDiameterView);

			//viewPanelGraphics.DrawEllipse(targetPen, Real2ViewX(targetPoint.x),Real2ViewY(targetPoint.y),1,1);
			
			Point2D pBallPosition = Predicator.GetBallPosition(1);
			viewPanelGraphics.DrawEllipse(ballPPen, Real2ViewX(pBallPosition.x)-ballDiameterView/2, Real2ViewY(pBallPosition.y)-ballDiameterView/2, ballDiameterView, ballDiameterView);
			pBallPosition = Predicator.GetBallPosition(2);
			viewPanelGraphics.DrawEllipse(ballPPen, Real2ViewX(pBallPosition.x)-ballDiameterView/2, Real2ViewY(pBallPosition.y)-ballDiameterView/2, ballDiameterView, ballDiameterView);
			
            /*
			if (theCoach != null)
				viewPanelGraphics.DrawEllipse(targetPen, Real2ViewX(theCoach.kickingPoint.x),Real2ViewY(theCoach.kickingPoint.y),2,2);
            */



			// do NOT draw locks
//
//			FIRARobotState selectedRobot = robotsListBox.Items[0] as FIRARobotState;
//			if (selectedRobot == null || PotencialDriver.angleLocks==null)
//				return;
//
//			firaDriverMutex.WaitOne();
//			foreach (PotencialDriver.AngleLock angleLock in PotencialDriver.angleLocks)
//			{
//				viewPanelGraphics.DrawLine(ballPen,  Real2ViewX(selectedRobot.x), Real2ViewY(selectedRobot.y), 
//					Real2ViewX(selectedRobot.x) + (float)(Math.Cos(angleLock.lockVector.Angle + angleLock.halfAngle)*angleLock.lockVector.Length*viewScale),
//					Real2ViewY(selectedRobot.y) + (float)(Math.Sin(angleLock.lockVector.Angle + angleLock.halfAngle)*angleLock.lockVector.Length*viewScale));
//				viewPanelGraphics.DrawLine(ballPen,  Real2ViewX(selectedRobot.x), Real2ViewY(selectedRobot.y), 
//					Real2ViewX(selectedRobot.x) + (float)(Math.Cos(angleLock.lockVector.Angle - angleLock.halfAngle)*angleLock.lockVector.Length*viewScale),
//					Real2ViewY(selectedRobot.y) + (float)(Math.Sin(angleLock.lockVector.Angle - angleLock.halfAngle)*angleLock.lockVector.Length*viewScale));
//				
//				viewPanelGraphics.DrawEllipse(targetPen, Real2ViewX(PotencialDriver.checkPoint.x),Real2ViewY(PotencialDriver.checkPoint.y),2,2);
//
//
//			}
//			firaDriverMutex.ReleaseMutex();
		}

		private void interfaceRefreshTimer_Tick(object sender, System.EventArgs e)
		{
			viewPanel_Paint(this,null);
		}


		private void viewPanel_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			targetPoint = new Point2D(View2RealX(e.X), View2RealY(e.Y));
			middleStatusLabel.Text = "location: "+targetPoint.ToLongString("f2");
		}

		private void rightStatusLabel_DoubleClick(object sender, System.EventArgs e)
		{
			oldTime = -1;
		}

		private void PotencialDriverForm_Load(object sender, System.EventArgs e)
		{
		
		}

		private void createCoachButton_Click(object sender, System.EventArgs e)
		{
			try
			{
				theCoach = new TheCoachOf5(aghDriver, pitchArea, goalWidth);
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message);
				return;
			}
			createCoachButton.Enabled = false;
			createCoachButton.Text = "coach created!";
			gameStateGroupBox.Enabled = true;
		}

		private void gameStateRadioButton_CheckedChanged(object sender, System.EventArgs e)
		{
			if (theCoach == null)
				return;

			if (haltRadioButton.Checked)
				theCoach.GameState = GameState.Off;
			else if (startPositionsRadioButton.Checked)
				theCoach.GameState = GameState.StartupPositions;
			else if (playRadioButton.Checked)
				theCoach.GameState = GameState.Play;		
		}

		private void maxVelocityTrackBar_Scroll(object sender, System.EventArgs e)
		{
			PotencialDriver.maxVelocity = (double)maxVelocityTrackBar.Value / 10;
			maxVelocityLabel.Text = "max velocity: "+PotencialDriver.maxVelocity.ToString("f1")+" m/s";
		}

        private void pickSelectedOnlyButton_Clicked(object sender, System.EventArgs e)
		{
            this.checkedListBox1.SetItemChecked(checkedListBox1.SelectedIndex, true);
            for (int i = 0; i < this.checkedListBox1.Items.Count; i++)
            {
                if (i != checkedListBox1.SelectedIndex)
                    this.checkedListBox1.SetItemChecked(i, false);
            }
            Strategies.StrategiesManager.permitOneOnlyStrategy((Type) checkedListBox1.SelectedItem);
		}

        private void strategyPermissionChanged(object sender, ItemCheckEventArgs e)
		{
            if (this.checkedListBox1.Items[e.Index] == typeof(BasicGoalKeeperStrategy))
                e.NewValue = CheckState.Checked;

            if (checkedListBox1.CheckedItems.Count == 1)
            {
                Boolean isCheckedItemBeingUnchecked = (e.CurrentValue == CheckState.Checked);
                if (isCheckedItemBeingUnchecked)
                    e.NewValue = CheckState.Checked;
            }
            bool permitState = e.NewValue == CheckState.Checked;
            if (permitState)
                Strategies.StrategiesManager.permitStrategy((Type)checkedListBox1.SelectedItem);
            else
                Strategies.StrategiesManager.forbidStrategy((Type)checkedListBox1.SelectedItem);
		}

        private void pickAllButton_Clicked(object sender, System.EventArgs e)
		{
            for (int i = 0; i < this.checkedListBox1.Items.Count; i++)
            {
                this.checkedListBox1.SetItemChecked(i, true);
                Strategies.StrategiesManager.permitStrategy((Type)checkedListBox1.Items[i]);
            }
		}
	}
}

